

#include "StdAfx.h"
#include "ModelIO_Util.h"

//#include <wrap/io_trimesh/import_ply.h>
#include <wrap/io_trimesh/import_stl.h>
#include <wrap/io_trimesh/import_obj.h>
#include <wrap/io_trimesh/import_off.h>
#include <wrap/io_trimesh/import_ptx.h>
#include <wrap/io_trimesh/import_vmi.h>
#include "Import_dat_lw.h"

//#include <wrap/io_trimesh/export_ply.h>
//#include <wrap/io_trimesh/export_stl.h>
//#include <wrap/io_trimesh/export_obj.h>
//#include <wrap/io_trimesh/export_vrml.h>
//#include <wrap/io_trimesh/export_dxf.h>
//#include <wrap/io_trimesh/export_vmi.h>
//#include <wrap/io_trimesh/export.h>

#include "MeshModel.h"

using namespace std;
using namespace vcg;

bool	ModelIO_Util::LoadFile( const char* lpszFile, const char* lpszFormat, CMeshModel* pModel, int& mask, vcg::CallBackPos *cb/* =0 */ )
{
	if( !pModel )
		return false;

	if( !Vcg_ImportFile( lpszFile, lpszFormat, pModel, mask, cb ) )
		return false;

	if( mask & vcg::tri::io::Mask::IOM_BITPOLYGONAL)
	{
		pModel->UpdateDataMask( CMeshModel::MM_POLYGONAL); // just to be sure. Hopefully it should be done in the plugin...
		/*int degNum = tri::Clean<CMeshO>::RemoveDegenerateFace( pModel->cm );
		if(degNum)
		GLA()->Logf(0,"Warning model contains %i degenerate faces. Removed them.",degNum);*/
		pModel->UpdateDataMask( CMeshModel::MM_FACEFACETOPO );
		vcg::tri::UpdateNormal<CMeshO>::PerBitQuadFaceNormalized( pModel->cm );
		vcg::tri::UpdateNormal<CMeshO>::PerVertexFromCurrentFaceNormal( pModel->cm );
	} // standard case
	else
	{
		vcg::tri::UpdateNormal<CMeshO>::PerFaceNormalized( pModel->cm );
		if( !( mask & vcg::tri::io::Mask::IOM_VERTNORMAL) )
			vcg::tri::UpdateNormal<CMeshO>::PerVertexAngleWeighted( pModel->cm );
	}

	vcg::tri::UpdateBounding<CMeshO>::Box( pModel->cm );					// updates bounding box

	if( pModel->cm.fn==0 && pModel->cm.en>0 )
	{
		if( mask & vcg::tri::io::Mask::IOM_VERTNORMAL )
			pModel->UpdateDataMask( CMeshModel::MM_VERTNORMAL );
	}
	else
		pModel->UpdateDataMask( CMeshModel::MM_VERTNORMAL );


	int delVertNum = vcg::tri::Clean<CMeshO>::RemoveDegenerateVertex( pModel->cm );
	int delFaceNum = vcg::tri::Clean<CMeshO>::RemoveDegenerateFace( pModel->cm );

	return true;
}

bool	ModelIO_Util::Vcg_ImportDat( const char* lpszFile, const char* lpszFormat, CMeshModel* pModel, vcg::CallBackPos *cb/* = 0*/ )
{
	bool normalsUpdated = false;
	// initializing mask
	if (cb != NULL)		(*cb)(0, "Loading...");

	CMeshO& m = pModel->cm;
	// initializing progress bar status
	//lxj:	
	string errorMsgFormat = "Error encountered while loading file:\n\"%1\"\n\nError details: %2";
	
	char fmt[ 10 ];
	strcpy( fmt, lpszFormat );
	strupr( fmt );
	
	if( strcmp( fmt, "DAT" ) == 0 )
	{
		int result = tri::io::Importer_dat_lw<CMeshO>::Open( m, lpszFile, cb );
	}

	if (cb != NULL)	(*cb)(99, "Done");

	return true;
}


bool	ModelIO_Util::Vcg_ImportFile( const char* lpszFile, const char* lpszFormat, CMeshModel* pModel, int& mask, vcg::CallBackPos *cb/* = 0*/ )
{
	bool normalsUpdated = false;
	// initializing mask
	mask = 0;
	if (cb != NULL)		(*cb)(0, "Loading...");

	CMeshO& m = pModel->cm;
	// initializing progress bar status
	//lxj:	
	string errorMsgFormat = "Error encountered while loading file:\n\"%1\"\n\nError details: %2";
	
	char fmt[ 10 ];
	strcpy( fmt, lpszFormat );
	strupr( fmt );
	//if( strcmp( fmt, "PLY" ) == 0 )
	//{
	//	tri::io::ImporterPLY<CMeshO>::LoadMask( lpszFile, mask );
	//	// small patch to allow the loading of per wedge color into faces.
	//	if( mask & tri::io::Mask::IOM_WEDGCOLOR ) 
	//		mask |= tri::io::Mask::IOM_FACECOLOR;

	//	pModel->Enable( mask );
	//	int result = tri::io::ImporterPLY<CMeshO>::Open( pModel->cm, lpszFile, mask, cb );
	//	if( result != 0 ) // all the importers return 0 on success
	//	{
	//		if( tri::io::ImporterPLY<CMeshO>::ErrorCritical( result ) )
	//		{
	//			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterPLY<CMeshO>::ErrorMsg(result));
	//			return false;
	//		}
	//	}
	//}
	if( strcmp( fmt, "STL" ) == 0 )
	{
		if (!tri::io::ImporterSTL<CMeshO>::LoadMask( lpszFile, mask ) )
		{
			//lxj:
			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterSTL<CMeshO>::ErrorMsg(tri::io::ImporterSTL<CMeshO>::E_CANTOPEN));
			return false;
		}
		pModel->Enable(mask);
		int result = tri::io::ImporterSTL<CMeshO>::Open( m, lpszFile, mask, cb );
		if (result != 0) // all the importers return 0 on success
		{
			//lxj:
			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterSTL<CMeshO>::ErrorMsg(result));
			return false;
		}
	}
	else if( strcmp( fmt, "OBJ" ) == 0 )
	{
		tri::io::ImporterOBJ<CMeshO>::Info oi;
		oi.cb = cb;
		if (!tri::io::ImporterOBJ<CMeshO>::LoadMask( lpszFile, oi ) )
			return false;
		pModel->Enable( oi.mask );

		int result = tri::io::ImporterOBJ<CMeshO>::Open( m, lpszFile, oi );
		if( result != tri::io::ImporterOBJ<CMeshO>::E_NOERROR )
		{
			if( result & tri::io::ImporterOBJ<CMeshO>::E_NON_CRITICAL_ERROR )
			{
				//lxj:
				int iiiii = 0;
				//errorMessage = errorMsgFormat.arg( lpszFile, tri::io::ImporterOBJ<CMeshO>::ErrorMsg( result ) );
			}
			else
			{
				//lxj:
				//errorMessage = errorMsgFormat.arg( lpszFile, tri::io::ImporterOBJ<CMeshO>::ErrorMsg( result ) );
				return false;
			}
		}

		if( oi.mask & tri::io::Mask::IOM_WEDGNORMAL )
			normalsUpdated = true;
		pModel->Enable(oi.mask);
		if( pModel->HasDataMask( CMeshModel::MM_POLYGONAL ) ) 
		{
			//lxj:
			int iii = 0;
			//AfxMessageBox( L"Mesh is Polygonal!" );
			//qDebug("Mesh is Polygonal!");
		}
		mask = oi.mask;
	}
	else if( strcmp( fmt, "DAT" ) == 0 )
	{
		int result = tri::io::Importer_dat_lw<CMeshO>::Open( m, lpszFile, cb );
	}
	else if( strcmp( fmt, "OFF" ) == 0 )
	{
		int loadMask;
		if( !tri::io::ImporterOFF<CMeshO>::LoadMask( lpszFile,loadMask ) )
		{
			//lxj:
			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOFF<CMeshO>::ErrorMsg(tri::io::ImporterOFF<CMeshO>::InvalidFile));
			return false;
		}
		pModel->Enable( loadMask );

		int result = tri::io::ImporterOFF<CMeshO>::Open( m, lpszFile, mask, cb );
		if (result != 0)  // OFFCodes enum is protected
		{
			//lxj:
			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOFF<CMeshO>::ErrorMsg(result));
			return false;
		}
	}
	else if( strcmp( fmt, "PTX" ) == 0 )
	{
		tri::io::ImporterPTX<CMeshO>::Info importparams;

		//lxj:
		/*importparams.meshnum = parlst.getInt("meshindex");
		importparams.anglecull =parlst.getBool("anglecull");
		importparams.angle = parlst.getFloat("angle");
		importparams.savecolor = parlst.getBool("usecolor");
		importparams.pointcull = parlst.getBool("pointcull");
		importparams.pointsonly = parlst.getBool("pointsonly");
		importparams.switchside = parlst.getBool("switchside");
		importparams.flipfaces = parlst.getBool("flipfaces");*/

		// if color, add to mesh
		if( importparams.savecolor )
			importparams.mask |= tri::io::Mask::IOM_VERTCOLOR;
		if(importparams.pointsonly)
			importparams.mask |= tri::io::Mask::IOM_VERTRADIUS;

		// reflectance is stored in quality
		importparams.mask |= tri::io::Mask::IOM_VERTQUALITY;

		pModel->Enable( importparams.mask );

		int result = tri::io::ImporterPTX<CMeshO>::Open( m, lpszFile, importparams, cb );
		if( result == 1 )
		{
			//lxj:
			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterPTX<CMeshO>::ErrorMsg(result));
			return false;
		}

		// update mask
		mask = importparams.mask;
	}
	else if( strcmp( fmt, "VMI" ) == 0 )
	{
		int loadMask;
		if( !tri::io::ImporterVMI<CMeshO>::LoadMask( lpszFile, loadMask ) )
			return false;
		pModel->Enable( loadMask );

		int result = tri::io::ImporterVMI<CMeshO>::Open( m, lpszFile, mask, cb );
		if( result != 0 )
		{
			//lxj:
			//errorMessage = errorMsgFormat.arg(fileName, tri::io::ImporterOFF<CMeshO>::ErrorMsg(result));
			return false;
		}
	}
	else
	{
		assert( 0 );
		return false;
	}

	// verify if texture files are present
	string missingTextureFilesMsg = "The following texture files were not found:\n";
	bool someTextureNotFound = false;
	for ( unsigned textureIdx = 0; textureIdx < m.textures.size(); ++textureIdx )
	{
		//lxj: is texture exist
		
		
		/*if (!QFile::exists( m.textures[textureIdx].c_str()))
		{
			missingTextureFilesMsg.append("\n");
			missingTextureFilesMsg.append(m.cm.textures[textureIdx].c_str());
			someTextureNotFound = true;
		}*/
	}

	if (someTextureNotFound)
	{
		//lxj:
		int iii = 0;
	}
	//Log("Missing texture files: %s", qPrintable(missingTextureFilesMsg));

	if (cb != NULL)	(*cb)(99, "Done");

	return true;
}

bool	ModelIO_Util::SaveFile( const char* lpszFile, const char* lpszFormat, CMeshModel* pModel, const int mask, vcg::CallBackPos *cb/* = 0*/ )
{
	return false;
}

void	ModelIO_Util::InitOpenParameter( const char* format, CMeshModel* pModel )
{

}

void	ModelIO_Util::ApplyOpenParameter( const char* format, CMeshModel* pModel )
{

}

void	ModelIO_Util::InitPreOpenParameter( const char* formatName, const char* filename )
{

}

void	ModelIO_Util::InitSaveParameter( const char* format, CMeshModel* pModel )
{

}